<template>
    <span @click="$parameters.value = '1,2-1'">click</span>
    <div id="rc-tree-container" class="rc-tree-container" />
    {{ $parameters.values }}

    <!-- <div class="test">
        <div v-for="(item,index) in $parameters.data" :key="index">
            <p>{{ item.name }}</p>
            <div v-for="(item,index) in $parameters.data" :key="index">
                <p>{{ item.name }}</p>
            </div>
        </div>
    </div> -->
</template>

<script lang="ts">
export default { name: 'Tree' }
</script>

<script lang="ts" setup>
// @ts-nocheck
import { reactive, onMounted, nextTick, h, render, watch } from 'vue'
// 箭头可选择前或后
// 前icon可设置，无需后icon
// id，name，children
// 可设置单选多选，传值逗号隔开string
const $parameters = reactive({
    data: [
        {
            name: '一级 1',
            id: '1',
            children: [
                {
                    name: '二级 1-1',
                    id: '1-1',
                    img: 'https://img1.baidu.com/it/u=250908197,2775802333&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
                    activeImg: 'https://img1.baidu.com/it/u=430561488,3826916573&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
                    children: [
                        { name: '三级 1-1-1', id: '1-1-1' },
                    ],
                },
            ],
        },
        {
            name: '一级 2',
            id: '2',
            children: [
                {
                    name: '二级 2-1',
                    id: '2-1',
                    disabled: true,
                    children: [
                        { name: '三级 2-1-1', id: '2-1-1' },
                    ],
                },
                {
                    name: '二级 2-2',
                    id: '2-2',
                    // children: [
                    //     { name: '三级 2-2-1', id: '2-2-1' },
                    // ],
                },
            ],
        },
        {
            name: '一级 3',
            id: '3',
            children: [
                {
                    name: '二级 3-1',
                    id: '3-1',
                    children: [
                        { name: '三级 3-1-1', id: '3-1-1' },
                    ],
                },
                {
                    name: '二级 3-2',
                    id: '3-2',
                    children: [
                        { name: '三级 3-2-1', id: '3-2-1' },
                    ],
                },
            ],
        },
    ],
    value: '',
    values: [],
    containerID: 'rc-tree-container',
    iconPosition: 'left',
    multiple: false,
    chooseAnyNode: true,
})
onMounted(() => {
    const treeContainer = document.querySelector(`#${$parameters.containerID}`)

    watch(() => $parameters.value, (newVal) => {
        $parameters.values = newVal === '' ? [] : newVal.split(',')
    })

    watch([
        () => $parameters.data,
        () => $parameters.values,
        () => $parameters.disabled,
    ], (newVal) => {
        console.log('watch')

        renderTree()
    }, { deep: true })

    // eslint-disable-next-line eqeqeq
    const hasValue = (id) => $parameters.values.findIndex((item) => item == id) !== -1

    treeContainer?.addEventListener('click', (event) => {
        const add = (target) => {
            $parameters.values.push(target.getAttribute('valueId'))
            $parameters.values = [...new Set($parameters.values)]
        }

        const remove = (target) => {
            const index = $parameters.values.findIndex((item) => item == target.getAttribute('valueId'))
            if (index !== -1) $parameters.values.splice(index, 1)
        }

        const setValue = (target) => {
            if (target.getAttribute('disabled') === 'true') return
            if ($parameters.multiple) { // 多选
                if (target.getAttribute('checked') === 'true') {
                    remove(target)
                } else {
                    add(target)
                }
            } else { // 单选
                // eslint-disable-next-line no-lonely-if
                if (target.getAttribute('checked') === 'true') {
                    remove(target)
                } else {
                    $parameters.values = []
                    add(target)
                }
            }
        }
        const collapse = (target) => {
            const nextEl = target.parentElement.nextElementSibling
            if (nextEl.className.indexOf('rc-tree-node') === -1) return
            // 收起
            if (nextEl.className.indexOf('collapsed') === -1) {
                nextEl.style.height = `${nextEl.scrollHeight}px`
                setTimeout(() => {
                    nextEl.style.height = '0px'
                })
                nextEl.classList.add('collapsed')
                target.classList.remove('rotated')
            } else { // 展开
                nextEl.style.height = `${nextEl.scrollHeight}px`
                setTimeout(() => {
                    nextEl.style.height = ''
                }, 300)
                nextEl.classList.remove('collapsed')
                target.classList.add('rotated')
            }
        }

        // icon点击 展开收起
        if (event.target.className.indexOf('rc-tree-collapse-icon') !== -1) {
            collapse(event.target)
        } else if (event.target.className.indexOf('rc-tree-text') !== -1) { // 文字点击
            if (!$parameters.chooseAnyNode && event.target.className.indexOf('node-father-text') !== -1) {
                collapse(event.target.querySelector('.rc-tree-collapse-icon'))
            } else {
                setValue(event.target)
            }
        } else if (event.target.className.indexOf('checkbox') !== -1) { // checkbox点击
            if ($parameters.chooseAnyNode || event.target.parentElement.className.indexOf('node-father-text') === -1) {
                setValue(event.target.parentElement)
            }
        }
    })

    const createVnode = (list, zIndex) => {
        const vnodes = []
        for (let i = 0; i < list.length; i++) {
            const element = list[i]
            const has = hasValue(element.id)
            if (element.children && element.children.length) {
                vnodes.push(h('div', { class: 'rc-tree-node collapsed node-father', zIndex }, [
                    h('p', {
                        class: 'rc-tree-text node-father-text rc-tree-collapsable',
                        disabled: element.disabled,
                        valueId: element.id,
                        checked: has,
                        style: { paddingLeft: `${zIndex * 2 - 1}em` },
                    }, [
                        h('span', { class: {
                            'rc-tree-collapse-icon': true,
                            'position-right': $parameters.iconPosition === 'right',
                        } }, '→'),
                        $parameters.multiple && h('span', {
                            class: {
                                checkbox: true,
                                'is-checked': has,
                            },
                            disabled: element.disabled,
                        }), (element.activeImg || element.img) && h('img', { src: has ? (element.activeImg || element.img) : element.img }),
                        element.name,
                    ]),
                    ...createVnode(element.children, zIndex + 1),
                ]))
            } else {
                vnodes.push(h('div', { class: 'rc-tree-node collapsed', zIndex }, [
                    h('p', {
                        class: 'rc-tree-text',
                        disabled: element.disabled,
                        valueId: element.id,
                        checked: has,
                        style: { paddingLeft: `${zIndex * 2 - 1}em` },
                    }, [$parameters.multiple && h('span', {
                        class: {
                            checkbox: true,
                            'is-checked': has,
                        },
                        disabled: element.disabled,
                    }), (element.activeImg || element.img) && h('img', { src: has ? (element.activeImg || element.img) : element.img }),
                    element.name]),
                ]))
            }
        }
        return vnodes
    }

    const renderTree = () => {
        console.log('renderTree')

        const vnode = h('div', { class: 'rc-tree-inner' }, createVnode($parameters.data, 0))
        console.log(vnode, treeContainer)
        render(vnode, treeContainer)
    }
    renderTree()
})

</script>
<style>
.rc-tree-container {
    height: 400px;
    padding: 4px;
    overflow: auto;
    border: 1px solid rgb(0 0 0 / 20%);
    border-radius: 3px;
    text-align: left;
}

.rc-tree-collapse-icon {
    display: inline-block;
    transition: 0.3s;
    user-select: none;
}

.rc-tree-collapse-icon.rotated {
    transform: rotate(90deg) !important;
}

.rc-tree-collapse-icon.position-right {
    position: absolute;
    right: 10px;
    transform: rotate(180deg);
}

.checkbox {
    display: inline-block;
    position: relative;
    box-sizing: border-box;
    width: 14px;
    height: 14px;
    margin: 0 6px;
    border: 1px solid #dcdfe6;
    border-radius: 2px;
}

.checkbox.is-indeterminate,
.checkbox.is-checked {
    border-color: #409eff;
    background-color: #409eff;
}

.checkbox::after {
    content: "";
    position: absolute;
    box-sizing: content-box;
    transform: rotate(45deg) scaleY(0);
    transform-origin: center;
    transition: transform 0.15s ease-in 0.05s;
    border: 1px solid #fff;
    border-top: 0;
    border-left: 0;
}

.checkbox.is-checked::after {
    top: 1px;
    left: 4px;
    width: 3px;
    height: 7px;
    transform: rotate(45deg) scaleY(1);
}

.rc-tree-text[disabled="true"] {
    color: rgb(155 155 155);
}

.rc-tree-text {
    position: relative;
    margin: 0;
    padding: 4px 0;
    cursor: pointer;
}

.rc-tree-text[checked="true"] {
    color: #409eff;
    font-weight: 700;
}

.rc-tree-text:hover {
    background-color: rgb(0 0 0 / 5%);
}

.rc-tree-node {
    height: auto;
    transition: 0.3s;
}

.rc-tree-node.collapsed {
    height: 0;
    overflow: hidden;
}

img {
    width: 20px;
    height: 20px;
    margin-right: 6px;
    vertical-align: sub;
}

/* .rc-tree-node {
    max-height: 9999px;
    transition: max-height 0.5s cubic-bezier(1, 0, 1, 0);
}

.rc-tree-node.collapsed {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
} */

.node-father[zIndex="0"] {
    height: auto;
}
</style>
